"""
操作系统管理工具函数
提供操作系统数据验证、格式化等工具方法
"""

import logging
import re
from datetime import datetime, date
from typing import Dict, Any, List, Optional, Tuple

logger = logging.getLogger(__name__)

class OsUtils:
    """操作系统工具类"""
    
    # 操作系统类型常量
    OS_TYPE_LINUX = "Linux"
    OS_TYPE_WINDOWS = "Windows"
    OS_TYPE_UNIX = "Unix"
    OS_TYPE_VMWARE = "VMware"
    OS_TYPE_OTHER = "其他"
    
    # 常见操作系统名称
    COMMON_OS_NAMES = [
        "CentOS", "Ubuntu", "Debian", "Red Hat", "SUSE",
        "Windows Server", "Windows 10", "Windows 11",
        "VMware ESXi", "VMware vCenter", "AIX", "HP-UX"
    ]
    
    def __init__(self):
        # 支持的操作系统类型
        self.valid_os_types = [
            self.OS_TYPE_LINUX,
            self.OS_TYPE_WINDOWS,
            self.OS_TYPE_UNIX,
            self.OS_TYPE_VMWARE,
            self.OS_TYPE_OTHER
        ]
        
        # 版本号正则表达式
        self.version_pattern = re.compile(r'^\d+(\.\d+)*([a-zA-Z0-9_-]*)?$')
        
        # 安装目录正则表达式
        self.install_dir_pattern = re.compile(r'^[a-zA-Z0-9/\\_\-:.\s]+$')
    
    def validate_os_data(self, os_data: Dict[str, Any], is_update: bool = False) -> Tuple[bool, str]:
        """
        验证操作系统数据
        
        Args:
            os_data: 操作系统数据
            is_update: 是否为更新操作
            
        Returns:
            (是否有效, 错误信息)
        """
        # 必填字段验证
        required_fields = ['asset_id', 'os_name', 'version']
        for field in required_fields:
            if not is_update or field in os_data:
                if field not in os_data or not os_data[field] or not str(os_data[field]).strip():
                    return False, f"字段 {field} 不能为空"
        
        # 操作系统名称验证
        if 'os_name' in os_data:
            os_name = str(os_data['os_name']).strip()
            if len(os_name) < 2 or len(os_name) > 100:
                return False, "操作系统名称长度必须在2-100个字符之间"
            
            # 检查是否包含非法字符
            if not re.match(r'^[a-zA-Z0-9\s\u4e00-\u9fa5\-_.]+$', os_name):
                return False, "操作系统名称包含非法字符"
        
        # 版本号验证
        if 'version' in os_data:
            version = str(os_data['version']).strip()
            if len(version) < 1 or len(version) > 50:
                return False, "版本号长度必须在1-50个字符之间"
            
            # 验证版本号格式
            if not self.version_pattern.match(version):
                return False, "版本号格式不正确，应为数字格式（如：7.6、10.0.19041等）"
        
        # 安装目录验证
        if 'install_dir' in os_data and os_data['install_dir']:
            install_dir = str(os_data['install_dir']).strip()
            if len(install_dir) > 200:
                return False, "安装目录路径长度不能超过200个字符"
            
            if not self.install_dir_pattern.match(install_dir):
                return False, "安装目录路径包含非法字符"
        
        # 安装日期验证
        if 'install_date' in os_data and os_data['install_date']:
            if isinstance(os_data['install_date'], str):
                try:
                    # 尝试解析日期字符串
                    datetime.strptime(os_data['install_date'], '%Y-%m-%d')
                except ValueError:
                    try:
                        datetime.strptime(os_data['install_date'], '%Y-%m-%d %H:%M:%S')
                    except ValueError:
                        return False, "安装日期格式不正确，应为YYYY-MM-DD或YYYY-MM-DD HH:MM:SS"
            elif not isinstance(os_data['install_date'], (date, datetime)):
                return False, "安装日期类型不正确"
        
        # 设备资产ID验证
        if 'asset_id' in os_data:
            asset_id = str(os_data['asset_id']).strip()
            if not asset_id:
                return False, "设备资产ID不能为空"
        
        return True, ""
    
    def format_os_data(self, os_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        格式化操作系统数据
        
        Args:
            os_data: 原始操作系统数据
            
        Returns:
            格式化后的数据
        """
        formatted_data = {}
        
        # 字符串字段去除空格
        string_fields = ['os_id', 'asset_id', 'os_name', 'version', 'install_dir']
        for field in string_fields:
            if field in os_data and os_data[field] is not None:
                formatted_data[field] = str(os_data[field]).strip()
        
        # 日期字段格式化
        date_fields = ['install_date']
        for field in date_fields:
            if field in os_data and os_data[field] is not None:
                if isinstance(os_data[field], str):
                    # 尝试解析日期字符串
                    try:
                        parsed_date = datetime.strptime(os_data[field], '%Y-%m-%d')
                        formatted_data[field] = parsed_date.date()
                    except ValueError:
                        try:
                            parsed_date = datetime.strptime(os_data[field], '%Y-%m-%d %H:%M:%S')
                            formatted_data[field] = parsed_date.date()
                        except ValueError:
                            # 如果无法解析，保持原样
                            formatted_data[field] = os_data[field]
                elif isinstance(os_data[field], datetime):
                    formatted_data[field] = os_data[field].date()
                else:
                    formatted_data[field] = os_data[field]
        
        # 复制其他字段
        for field, value in os_data.items():
            if field not in formatted_data and field not in string_fields + date_fields:
                formatted_data[field] = value
        
        return formatted_data
    
    def get_os_display_name(self, os_name: str, version: str) -> str:
        """
        获取操作系统显示名称
        
        Args:
            os_name: 操作系统名称
            version: 版本号
            
        Returns:
            显示名称
        """
        if not os_name:
            return "未知操作系统"
        
        display_name = os_name
        if version:
            display_name += f" {version}"
        
        return display_name
    
    def get_os_type(self, os_name: str) -> str:
        """
        根据操作系统名称判断操作系统类型
        
        Args:
            os_name: 操作系统名称
            
        Returns:
            操作系统类型
        """
        if not os_name:
            return self.OS_TYPE_OTHER
        
        os_name_lower = os_name.lower()
        
        if any(keyword in os_name_lower for keyword in ['centos', 'ubuntu', 'debian', 'red hat', 'suse', 'linux']):
            return self.OS_TYPE_LINUX
        elif any(keyword in os_name_lower for keyword in ['windows']):
            return self.OS_TYPE_WINDOWS
        elif any(keyword in os_name_lower for keyword in ['unix', 'aix', 'hp-ux', 'solaris']):
            return self.OS_TYPE_UNIX
        elif any(keyword in os_name_lower for keyword in ['vmware', 'esxi', 'vcenter']):
            return self.OS_TYPE_VMWARE
        else:
            return self.OS_TYPE_OTHER
    
    def validate_install_directory(self, install_dir: str, os_type: str) -> Tuple[bool, str]:
        """
        验证安装目录是否符合操作系统类型
        
        Args:
            install_dir: 安装目录
            os_type: 操作系统类型
            
        Returns:
            (是否有效, 错误信息)
        """
        if not install_dir:
            return True, ""  # 安装目录可以为空
        
        install_dir = install_dir.strip()
        
        if os_type == self.OS_TYPE_WINDOWS:
            # Windows路径验证
            if not (install_dir.startswith('C:\\') or install_dir.startswith('D:\\') or 
                   install_dir.startswith('E:\\') or install_dir.startswith('F:\\')):
                return False, "Windows系统安装目录应以驱动器字母开头（如C:\\）"
            
            if not re.match(r'^[a-zA-Z]:\\[^<>:"|?*]*$', install_dir):
                return False, "Windows安装目录路径格式不正确"
        
        elif os_type in [self.OS_TYPE_LINUX, self.OS_TYPE_UNIX]:
            # Linux/Unix路径验证
            if not install_dir.startswith('/'):
                return False, "Linux/Unix系统安装目录应以/开头"
            
            if not re.match(r'^/[a-zA-Z0-9_\-./]*$', install_dir):
                return False, "Linux/Unix安装目录路径格式不正确"
        
        elif os_type == self.OS_TYPE_VMWARE:
            # VMware路径验证
            if not install_dir.startswith('/'):
                return False, "VMware系统安装目录应以/开头"
        
        return True, ""
    
    def get_supported_os_names(self) -> List[str]:
        """
        获取支持的操作系统名称列表
        
        Returns:
            操作系统名称列表
        """
        return self.COMMON_OS_NAMES.copy()
    
    def format_install_directory(self, install_dir: str, os_type: str) -> str:
        """
        根据操作系统类型格式化安装目录
        
        Args:
            install_dir: 原始安装目录
            os_type: 操作系统类型
            
        Returns:
            格式化后的安装目录
        """
        if not install_dir:
            return ""
        
        install_dir = install_dir.strip()
        
        # 统一路径分隔符
        if os_type == self.OS_TYPE_WINDOWS:
            # Windows使用反斜杠
            install_dir = install_dir.replace('/', '\\')
        else:
            # Linux/Unix使用正斜杠
            install_dir = install_dir.replace('\\', '/')
        
        # 移除末尾的路径分隔符（除非是根目录）
        if len(install_dir) > 1 and install_dir[-1] in ['/', '\\']:
            install_dir = install_dir[:-1]
        
        return install_dir
    
    def is_os_compatible_with_asset(self, os_name: str, asset_type: str) -> Tuple[bool, str]:
        """
        检查操作系统是否与设备资产类型兼容
        
        Args:
            os_name: 操作系统名称
            asset_type: 设备资产类型
            
        Returns:
            (是否兼容, 说明信息)
        """
        os_type = self.get_os_type(os_name)
        
        # 服务器类型设备
        if asset_type in ['服务器', 'SERVER']:
            if os_type in [self.OS_TYPE_LINUX, self.OS_TYPE_WINDOWS, self.OS_TYPE_UNIX]:
                return True, "兼容"
            elif os_type == self.OS_TYPE_VMWARE:
                return True, "兼容（虚拟化平台）"
            else:
                return False, "服务器通常安装Linux、Windows或Unix系统"
        
        # PC机类型设备
        elif asset_type in ['PC机', 'PC']:
            if os_type == self.OS_TYPE_WINDOWS:
                return True, "兼容"
            elif os_type == self.OS_TYPE_LINUX:
                return True, "兼容（Linux桌面）"
            else:
                return False, "PC机通常安装Windows系统"
        
        # 虚拟机管理平台 - 特殊处理：vCenter等应作为OS实例
        elif asset_type in ['虚拟机管理平台', 'VM_PLATFORM']:
            if os_type == self.OS_TYPE_VMWARE:
                return True, "兼容（虚拟机管理平台作为OS实例）"
            else:
                return False, "虚拟机管理平台通常安装VMware系统"
        
        # 安全设备 - 特殊处理：通常不经过OS模块，直接关联业务系统
        elif asset_type in ['安全设备', 'SECURITY_DEVICE']:
            if os_type in [self.OS_TYPE_LINUX, self.OS_TYPE_UNIX]:
                return True, "兼容（注意：安全设备通常直接关联业务系统）"
            else:
                return False, "安全设备通常基于Linux或Unix系统"
        
        # 分布式存储
        elif asset_type in ['分布式存储', 'DISTRIBUTED_STORAGE']:
            if os_type in [self.OS_TYPE_LINUX, self.OS_TYPE_UNIX]:
                return True, "兼容"
            else:
                return False, "分布式存储通常基于Linux系统"
        
        # 其他类型
        else:
            return True, "未知设备类型，请手动确认兼容性"
    
    def is_special_scenario_os(self, os_name: str, asset_type: str) -> Tuple[bool, str]:
        """
        判断是否为特殊场景的操作系统
        
        Args:
            os_name: 操作系统名称
            asset_type: 设备资产类型
            
        Returns:
            (是否为特殊场景, 场景类型)
        """
        os_type = self.get_os_type(os_name)
        
        # 虚拟机管理平台场景
        if asset_type in ['虚拟机管理平台', 'VM_PLATFORM'] and os_type == self.OS_TYPE_VMWARE:
            if 'vcenter' in os_name.lower() or 'esxi' in os_name.lower():
                return True, "虚拟机管理平台"
        
        return False, ""
    
    def get_os_recommendations(self, asset_type: str) -> List[str]:
        """
        根据设备资产类型获取推荐的操作系统
        
        Args:
            asset_type: 设备资产类型
            
        Returns:
            推荐的操作系统列表
        """
        recommendations = []
        
        if asset_type in ['服务器', 'SERVER']:
            recommendations = [
                "CentOS 7.6", "CentOS 8.4", "Ubuntu Server 20.04",
                "Ubuntu Server 22.04", "Red Hat Enterprise Linux 8",
                "Windows Server 2019", "Windows Server 2022"
            ]
        
        elif asset_type in ['PC机', 'PC']:
            recommendations = [
                "Windows 10", "Windows 11", "Ubuntu Desktop 22.04"
            ]
        
        elif asset_type in ['虚拟机管理平台', 'VM_PLATFORM']:
            recommendations = [
                "VMware ESXi 7.0", "VMware ESXi 8.0", "VMware vCenter 7.0"
            ]
        
        elif asset_type in ['安全设备', 'SECURITY_DEVICE']:
            recommendations = [
                "CentOS 7.6", "Red Hat Enterprise Linux 8",
                "Ubuntu Server 20.04"
            ]
        
        elif asset_type in ['分布式存储', 'DISTRIBUTED_STORAGE']:
            recommendations = [
                "CentOS 7.6", "CentOS 8.4", "Ubuntu Server 20.04"
            ]
        
        return recommendations
